package com.starleague.battletech.hexagonal.jpa.appengine;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PostLoad;
import javax.persistence.PostUpdate;

import com.starleague.battletech.game.jpa.appengine.BattletechGameGae;
import com.starleague.battletech.hexagonal.IBattletechHexGrid;
import com.starleague.hexagonal.HexException;
import com.starleague.hexagonal.HexOutOfBoundsException;
import com.starleague.hexagonal.IHexCoordinate;
import com.starleague.hexagonal.flat.jpa.appengine.AbstractFlatHexGridGae;

@Entity(name = "BATTLETECH_HEX_GRID")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class BattletechHexGridGae
        extends AbstractFlatHexGridGae
        implements IBattletechHexGrid
{
    @OneToOne(mappedBy = "hexGrid", fetch = FetchType.LAZY, optional = false)
    private BattletechGameGae game;

    @OneToMany(mappedBy = "hexGrid", cascade = CascadeType.ALL)
    private List<BattletechHexGae> hexList = new ArrayList<>();

    BattletechHexGridGae(BattletechGameGae game,
                         int minGridX,
                         int minGridY,
                         int numHexesX,
                         int numHexesY)
    {
        super(minGridX, minGridY, numHexesX, numHexesY);
        this.game = game;
    }

    protected BattletechHexGridGae()
    {
        //
    }

    @Override
    public BattletechGameGae getGame()
    {
        return this.game;
    }

    // @Override
    // public List<BattletechHexGae> getHexList()
    // {
    // return this.hexList;
    // }

    @Override
    public BattletechHexGae getHexAt(IHexCoordinate hexCoordinate) throws HexOutOfBoundsException
    {
        return (BattletechHexGae) super.getHexAt(hexCoordinate);
    }

    // TODO: Override setHex instead of using a new method addHex()
    void addHex(BattletechHexGae hex) throws HexException
    {
        setHex(hex);
        this.hexList.add(hex);
    }

    @PostLoad
    public void postLoad()
    {
        try
        {
            setHexes(this.hexList);
        }
        catch (HexException e)
        {
            throw new RuntimeException(e);
        }
    }

    // This may seem unnecessary, but it is actually very important
    @PostUpdate
    public void postUpdate()
    {
        try
        {
            setHexes(this.hexList);
        }
        catch (HexException e)
        {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Map<String, Object> infoProperties()
    {
        Map<String, Object> infoPropertyMap = super.infoProperties();
        infoPropertyMap.put("hexes", this.hexList);
        return infoPropertyMap;
    }
}
